home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / docs / ippon / eshot / 6 / eshot.c next >
C/C++ Source or Header  |  2000-07-07  |  5KB  |  230 lines

  1. /* eshot.c */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <math.h>        /* sin,cos を使うために */
  6. #include <sys/iocs.h>
  7. #include "XSP2lib.H"
  8.  
  9. #define PCG_MAX    32        /* パターンデータの個数 */
  10.  
  11. static char pcg_alt[PCG_MAX + 1];    /* PCG配置管理テーブル */
  12. static char pcg_dat[PCG_MAX * 128];    /* PCGデータファイル読み込みバッファ */
  13.  
  14. static unsigned short pal_dat[16][15];    /* パレットデータ */
  15.  
  16.  
  17. #define ESHOT_MAX    200    /* 敵弾最大数 */
  18. #define ESHOT_SPEED    0.75    /* 敵弾の速度 */
  19.  
  20.  
  21. /* 敵弾構造体 */
  22. typedef struct _eshot {
  23.     signed short x;        /* 敵弾のX座標 */
  24.     signed short y;        /*  〃 Y座標 */
  25.     unsigned char type;    /*  〃 種類(=0 なら未使用) */
  26.     signed int lx, ly;    /* 32bit X,Y 座標 ( l = longword ) */
  27.     signed int vx, vy;    /* 32bit X,Y 速度 ( v = velocity ) */
  28.     struct _eshot *next;    /* 次の構造体へのポインタ */
  29. } ESHOT;
  30.  
  31. ESHOT *eshot_top;        /* 使用中のワークのリスト */
  32. ESHOT *eshot_null_top;        /* 未使用ワークのリスト */
  33. ESHOT eshot[ESHOT_MAX];    /* ワーク */
  34.  
  35.  
  36.  
  37. typedef struct {
  38.     signed int x, y;
  39. } VECTOR;
  40.  
  41. VECTOR xytable[256];        /* sin,cos テーブル */
  42.  
  43.  
  44.  
  45. /* ゲーム開始時に呼ばれる */
  46. void EshotInit (void)
  47. {
  48.     int i;
  49.  
  50.     /* リストをつなげる */
  51.     eshot_top = NULL;
  52.     eshot_null_top = eshot;
  53.     for (i = 0; i < ESHOT_MAX; i++)
  54.         eshot[i].next = &eshot[i + 1];    /* 次を指すようにする */
  55.  
  56.     eshot[ESHOT_MAX - 1].next = NULL;    /* 「一番最後の次」はない */
  57. }
  58.  
  59.  
  60.  
  61. /* 敵弾出現時に呼ばれる */
  62. /* 引き数 : 種類, X座標, Y座標, 角度 */
  63. void EshotAlloc (unsigned char type, signed short x, signed short y, unsigned char angle)
  64. {
  65.     ESHOT *p;
  66.  
  67.     if (eshot_null_top == NULL)    /* ワークの空きはあるか? */
  68.         return;
  69.  
  70.     p = eshot_null_top;
  71.     eshot_null_top = p->next;
  72.     p->next = eshot_top;
  73.     eshot_top = p;
  74.  
  75.     p->lx = (x - 8) * 65536;    /* (8,8) がスプライト座標の中心なので補正 */
  76.     p->ly = (y - 8) * 65536;
  77.     p->vx = xytable[angle].x;
  78.     p->vy = xytable[angle].y;
  79.     p->type = type;
  80. }
  81.  
  82.  
  83.  
  84. /* 垂直同期ごとに呼ばれる */
  85. void EshotMove (void)
  86. {
  87.     ESHOT *p, *q;
  88.  
  89.     p = eshot_top;        /* 現在注目しているワーク */
  90.     q = NULL;        /* 1つ前のワーク(ワーク削除時に必要) */
  91.  
  92.     while (p != NULL) {
  93.         p->lx += p->vx;    /* vx だけ移動 */
  94.         p->ly += p->vy;    /* vy だけ移動 */
  95.  
  96.         p->x = p->lx / 65536;    /* lx の整数部を取り出して x に */
  97.         p->y = p->ly / 65536;    /* ly の整数部を取り出して y に */
  98.  
  99.         /* 敵弾が画面外に出たか? */
  100.         if ((p->x < 0) || (p->x > 256 + 16) || (p->y < 0) || (p->y > 256 + 16)) {
  101.             /* 画面外に出たので消去 */
  102.             if (q == NULL) {    /* リストの一番最初を削除 */
  103.                 eshot_top = p->next;
  104.                 p->next = eshot_null_top;
  105.                 eshot_null_top = p;
  106.                 q = NULL;
  107.                 p = eshot_top;
  108.             } else {
  109.                 q->next = p->next;
  110.                 p->next = eshot_null_top;
  111.                 eshot_null_top = p;
  112.                 p = q->next;
  113.             }
  114.         } else {
  115.             xsp_set (p->x, p->y, p->type, 0x033f);
  116.  
  117.             q = p;
  118.             p = p->next;
  119.         }
  120.     }
  121. }
  122.  
  123.  
  124.  
  125. int main (int argc, char *argv[])
  126. {
  127.     FILE *fp;
  128.     int i, j;
  129.     int game_over = 0;
  130.     unsigned char angle = 0;    /* 次に撃つ弾の角度 */
  131.     unsigned char type = 1;    /* 次に撃つ弾の種類 */
  132.     int sprites;        /* スプライトの枚数 */
  133.  
  134.     if (argc != 1) {
  135.         printf (
  136.                    "敵弾テストその6 ESHOT.X\n"
  137.                    "        programmed by Mitsuky <FreeSoftware>\n"
  138.                    "空きのワークもリスト構造で管理するようにした\n"
  139.             );
  140.         exit (-1);
  141.     }
  142.     printf ("データテーブルを作成します。\n");
  143.     for (i = 0; i < 256; i++) {
  144.         xytable[i].x = (signed int) (cos (2.0 * M_PI * (long) i / 256.0) * 65536.0 * ESHOT_SPEED);
  145.         xytable[i].y = (signed int) (sin (2.0 * M_PI * (long) i / 256.0) * 65536.0 * ESHOT_SPEED);
  146.     }
  147.  
  148.  
  149.     _iocs_crtmod (10);    /* 256x256ドット グラフィック画面 256色 2画面 */
  150.     _iocs_g_clr_on ();    /* グラフィック画面の初期化 */
  151.     _iocs_sp_init ();    /* スプライトの初期化 */
  152.     _iocs_sp_on ();
  153.  
  154.     /* pcg_dat にパターンデータを読み込む */
  155.     fp = fopen ("ESHOT.SP", "rb");
  156.     fread (pcg_dat, sizeof (char), PCG_MAX * 128, fp);
  157.     fclose (fp);
  158.  
  159.     /* pal_buf に一旦パレットデータを読み込む */
  160.     fp = fopen ("ESHOT.PAL", "rb");
  161.     fread (pal_dat, sizeof (unsigned short), 16 * 15, fp);
  162.     fclose (fp);
  163.     /* パレットデータを定義 */
  164.     /* (1パレットブロック=16色) × (15ブロックぶん) 定義する */
  165.     {
  166.         unsigned short *p = (unsigned short *) pal_dat;
  167.         for (i = 1; i < 15; i++)
  168.             for (j = 0; j < 16; j++)
  169.                 _iocs_spalet (0x80000000 | j, i, *p++);
  170.     }
  171.  
  172.     xsp_on ();
  173.     xsp_mode (3);
  174.     /* パターンデータを定義 */
  175.     xsp_pcgdat_set (pcg_dat, pcg_alt, sizeof (pcg_alt));
  176.  
  177.     /* グラフィック画面に線を引く */
  178.     {
  179.         struct _lineptr lp;
  180.         lp.x1 = 0;
  181.         lp.y1 = 128;
  182.         lp.x2 = 255;
  183.         lp.y2 = 128;
  184.         lp.color = 15;
  185.         lp.linestyle = 0xaaaa;
  186.         _iocs_line (&lp);
  187.         lp.x1 = 128;
  188.         lp.y1 = 0;
  189.         lp.x2 = 128;
  190.         lp.y2 = 255;
  191.         _iocs_line (&lp);
  192.     }
  193.  
  194.     printf ("ジョイスティックの\n"
  195.         " [B] ボタンを押すと弾を撃ちます\n"
  196.         " [A] ボタンを押すと終了します\n");
  197.  
  198.  
  199.     EshotInit ();
  200.  
  201.     do {
  202.         xsp_vsync (0);    /* 垂直同期待ち */
  203.         j = _iocs_joyget (0);    /* ジョイスティック0番 */
  204.  
  205.         /* [A] ボタンが押されたか? */
  206.         if ((j & 0b00100000) == 0)
  207.             game_over = !0;        /* ゲームオーバーに */
  208.  
  209.         /* [B] ボタンが押されたか? */
  210.         if ((j & 0b1000000) == 0) {
  211.             EshotAlloc (type, 144, 144, angle);    /* 種類 type の敵弾を座標(144,144)、角度 angle で発生 */
  212.             angle += 8;    /* 角度を進める */
  213.             type++;    /* 種類を進める(意味無し) */
  214.             if (type > 5)
  215.                 type = 1;
  216.         }
  217.         EshotMove ();
  218.         sprites = xsp_out ();    /* 表示 */
  219.  
  220.         printf ("弾数 = %3d  \n\x0b", sprites);
  221.         /* 0x0b はカーソルを1行上に移動する */
  222.         /* Human68K ユーザーズマニュアルの付録 ASCII 制御コードの欄参照 */
  223.     } while (!game_over);
  224.  
  225.     xsp_off ();
  226.  
  227.     _iocs_crtmod (16);
  228.     return (0);
  229. }
  230.